package airthmetic.exercise.sort;

import java.text.DecimalFormat;

public abstract class Sort<T extends Comparable<T>> implements Comparable<Sort<T>> {

    protected T[] array;
    private int cmpCount;
    private int swapCount;
    private long time;
    private DecimalFormat fmt = new DecimalFormat("#.00");

    protected abstract void sort();

    // 封装排序
    protected void sort(T[] array) {
        if (array == null || array.length < 2) return;
        this.array = array;
        long beginTime = System.currentTimeMillis();
        sort();
        time = System.currentTimeMillis() - beginTime;
    }

    // 比较 时间短的在最前面 时间一样比较 比较次数 比较次数一样 比较交换次数
    @Override
    public int compareTo(Sort<T> o) {
        long result = (long) time - o.time;
        if (result != 0) return (int) result;
        result = (long) cmpCount - o.cmpCount;
        if (result != 0) return (int) result;
        return (int) swapCount - o.swapCount;
    }

  /*  public static void main(String[] args) {
        Integer[] arr1 = {77, 2, 15, 20, 3};
        Integer[] arr2 = {77, 2, 15, 20, 3};
        Integer[] arr3 = {2, 15, 20};
        Integer[] arr4 = {77, 2, 15, 20, 3};

//        // 冒泡排序
//        for (int i = arr1.length - 1; i > 0; i--) {
//            for (int j = 1; j <= i; j++) {
//                if (arr1[j - 1] > arr1[j]) {
//                    Integer temp = arr1[j - 1];
//                    arr1[j - 1] = arr1[j];
//                    arr1[j] = temp;
//                }
//            }
//        }
//
//        for (Integer integer : arr1) {
//            System.out.println(integer);
//        }
//
//        // 冒泡排序优化 如果遍历一次发现没有位置变化 退出排序
//        for (int i = arr2.length - 1; i > 0; i--) {
//            boolean sorted = true;
//            for (int j = 1; j <= i; j++) {
//                if (arr2[j - 1] > arr2[j]) {
//                    Integer temp = arr2[j - 1];
//                    arr2[j - 1] = arr2[j];
//                    arr2[j] = temp;
//                    sorted = false;
//                }
//            }
//            if (sorted) break;
//        }
//
//        for (Integer integer : arr2) {
//            System.out.println(integer);
//        }

//        // 冒泡排序优化 记录最后一次交换位置下次从最后交换位置继续
//        for (int i = arr3.length - 1; i > 0; i--) {
//            int endIndex = 1;
//            for (int j = 1; j <= i; j++) {
//                if (arr3[j - 1] > arr3[j]) {
//                    Integer temp = arr3[j - 1];
//                    arr3[j - 1] = arr3[j];
//                    arr3[j] = temp;
//                    endIndex = j;
//                }
//            }
//            i = endIndex;
//        }
//
//        for (Integer integer : arr3) {
//            System.out.println(integer);
//        }

        // 选择排序  找到最大的值放到最后
        for (int i = arr4.length - 1; i > 0; i--) {
            int tempMaxIndex = 0;
            for (int j = 0; j <= i; j++) {
                if (arr4[j] > arr4[tempMaxIndex]) {
                    tempMaxIndex = j;
                }
            }
            int temp = arr4[i];
            arr4[i] = arr4[tempMaxIndex];
            arr4[tempMaxIndex] = temp;
        }

        for (Integer integer : arr4) {
            System.out.println(integer);
        }
    }*/

    /*
     * 返回值等于0，代表 array[i1] == array[i2]
     * 返回值小于0，代表 array[i1] < array[i2]
     * 返回值大于0，代表 array[i1] > array[i2]
     */
    protected int cmp(int i1, int i2) {
        cmpCount++;
        return array[i1].compareTo(array[i2]);
    }

    protected int cmp(T v1, T v2) {
        cmpCount++;
        return v1.compareTo(v2);
    }

    // 交换元素
    protected void swap(int i1, int i2) {
        swapCount++;
        T tmp = array[i1];
        array[i1] = array[i2];
        array[i2] = tmp;
    }

    private String numberString(int number) {
        if (number < 10000) return "" + number;

        if (number < 100000000) return fmt.format(number / 10000.0) + "万";
        return fmt.format(number / 100000000.0) + "亿";
    }

    @Override
    public String toString() {
        String timeStr = "耗时：" + (time / 1000.0) + "s(" + time + "ms)";
        String compareCountStr = "比较：" + numberString(cmpCount);
        String swapCountStr = "交换：" + numberString(swapCount);
        return "【" + getClass().getSimpleName() + "】\n"
                + timeStr + " \t"
                + compareCountStr + "\t "
                + swapCountStr + "\n"
                + "------------------------------------------------------------------";

    }

}
